package com.zzb;

public class ReadMe {
    /**
     * 2023-2-7 数据库基础
     * 项目制作流程
     * 1.创建maven空项目
     * 2.创建web项目：引入web模块
     * 3.导入需要的jar包依赖：
     *      servlet包，
     *      Lombok包，
     *      io流包（文件上传）,
     *      mysql数据库包
     *      json包
     * 4.导入前端模板:x-admin(不要修改这里面的任何一个代码)
     * 5.创建Java的包（三层架构的包）
     *      servlet
     *      service
     *      dao
     *      util
     *      model
     * 6.创建web的包（web目录结构的包）
     *      html
     *      css
     *      js
     *      img
     * 7.配置tomcat，启动项目
     * ----------------------------------------------------
     * 8.一个完整的前后端流程
     *      以登录为例：
     *      1.创建登录页面
     *      2.修改登录页面的html和css代码
     *      3.引入js文件(js和html代码不要写在一起)
     *      4.所有页面数据都通过ajax传递到Java后台
     *      -----
     *      java 后台：
     *      1.servlet  六大步骤：乱码，取得前端的值，封装到model，调用service，得到返回数据，传递给前端
     *      2.service  处理逻辑关系，和调用dao层
     *      3.dao    调用jdbc
     *      4.JDBC 工具类，固定用法，
     * -----------------------------------------------------------
     * 数据库：
     * 1.数据库是什么？
     * 2.mysql优势？
     * 3.MySQL的应用场景？
     * 4.怎么用？
     * --------------------
     * 1.安装MySQL软件和配置环境变量（可不配置）：
     *      注意：在安装过程中，出现安装服务错误，则需要重新安装，
     *          重新安装之前，需要删除注册表里面的内容
     * 2.安装MySQL要安装哪些内容呢？
     *      1.MySQL service 服务
     *      2.MySQL workbench 桌面端（Navicat） sql yog
     *      3.connector/J
     * 3.连接数据库：
     * 4.创建数据：CREATE SCHEMA `canyin04` ;
     * 5.创建表：应该创建什么表？和第三阶段model一一对应
     *      表名和类名一一对应
     *      列名和类的属性名一一对应
     *      mysql数据类型和Java属性的数据类型一一对应（可以不用绝对对应）
     *      每一个表都应该有一个主键：每一条数据保证唯一
     *      数据库的列名命名规则，以下划线的形式line_phone
     * 6.数据库的数据引擎innoDB和MyISAM的区别？
     * 7.mysql的数据类型？
     *      mysql              java
     *      int
     *      tinyint             byte
     *      smallint             short
     *      int                 int
     *      bigint              long
     *      char                 String
     *      varchar             String
     *      text                String
     *      date,time,datetime   date
     *      decimal           BigDecimal
     *     所有Java类型在数据库都可以用varchar
     * 8.char，varchar，text的区别？
     *      char用于固定长度（长度差不多） 255之内的字符
     *      varchar用于不定长度  小于65535用varchar
     *      text用于很长的字符  其他用text
     *      char(45)和varchar(45)的区别？
     * 9.数据库应该有一些共同的列名
     *      id  主键表示唯一 要选择三个选项：1.PK,2.NN,3.AI
     *      create_time 创建时间
     *      update_time 更新时间
     *      enable 数据状态
     *      remark  备注
     * 10.创建表代码
     *      CREATE TABLE `company` (
     *   `id` INT NOT NULL AUTO_INCREMENT,
     *   `logo` VARCHAR(200) NULL  DEFAULT '',
     *   `phone` CHAR(11) NULL COMMENT '手机',
     *   `net` VARCHAR(45) NULL COMMENT '网址',
     *   `address` VARCHAR(200) NULL DEFAULT '',
     *   `version` VARCHAR(45) NULL DEFAULT '',
     *   `email` VARCHAR(45) NULL DEFAULT '',
     *   `line_phone` VARCHAR(45) NULL DEFAULT '',
     *   `content` VARCHAR(45) NULL DEFAULT '',
     *   `create_time` DATETIME NULL DEFAULT '',
     *   `update_time` DATETIME NULL DEFAULT now(),
     *   `enable` TINYINT(4) NULL DEFAULT -1,
     *   `remark` VARCHAR(200) NULL DEFAULT '',
     *   PRIMARY KEY (`id`));
     *   注意：最好创建表的时候不要出现null的情况，
     * 11.修改的表列的sql语句
     *      ALTER TABLE `company`
     *      CHANGE COLUMN `logo` `logo` VARCHAR(200) NULL DEFAULT '' ,
     * 12.删除表
     *      DROP TABLE `company`;
     * 13.查询表
     *        show tables;
     * -----------------------------------------
     * 14.新增数据的sql
     *      INSERT INTO `company` (`logo`, `phone`, `net`, `address`, `version`, `email`, `line_phone`, `content`,
     * `create_time`, `update_time`, `enable`, `remark`)
     * VALUES ('1', '1', '1', '1', '1', '1', '1', '1',
     * '2022-2-22', '2022-3-30', '1', '1');
     * 15.查询数据
     *      SELECT * FROM company;
     * 16.修改sql语句
     *      UPDATE `company` SET
     * `logo` = '2', `phone` = '2', `net` = '2', `address` = '2',
     * `version` = '2', `email` = '2', `line_phone` = '2',
     * `content` = '2', `create_time` = '2022-05-22 00:00:00',
     * `update_time` = '2022-05-30 00:00:00', `enable` = '5', `remark` = '5'
     * WHERE (`id` = '4');
     * 17.删除数据
     * delete from company where id=3;
     *  注意：删除后，数据库还保留当前数据，可以恢复
     *  truncate company; 删除所有数据，不能恢复
     *  drop company;删除表结构
     *  面试：delete和truncate和drop的区别？
     *  -----------------------------------
     *  今日学习的知识点：
     *  1.数据库创建
     *  2.表创建，删除，更新列，查询
     *  3.表数据的创建，更新，删除，查询
     *  4.数据的导入导出
     *  5.数据的权限控制(连接其他人的数据库，必须分配权限才能连接)
     */
    /**
     * 2023-2-8 数据库查询
     * 1.建表的时候，如果是两个对象，他们之间应该存在某种关系
     *      一对一
     *      一对多
     *      多对一
     *      多对多
     *      怎么来分表？把经常需要修改的列放一个表，把不经常需要修改的放一个表
     *      用户信息表：在用户信息表里面多写其他表的id
     *      user(id,password_id,public_id,private_id)
     *      如果是一对多或者多对一，则在"多"的这个表里面创建一个"一“的id
     *      密码表：将用户和密码单独放一个表
     *      公开信息表：昵称，头像，性别
     *      自己私有表：手机，身份证，email，生日
     *      地址：可能会有多个，则需要另外一个表address(id,user_id);
     *      爱好表：
     *      更新时间信息表：update_time，remark
     *      -------------------------------------
     *      如果不想让多个表里面有其他表的id，则可以考虑创建一个关系表
     *      --------------------------------------------------
     * 2.以后查询的时候遇到or的时候要写括号
     * 3.sql注入?
     * 4.sql模糊查询可以用正则表达式？
     * 5.排序
     *      select * from product order by id desc;
     *      select * from product order by id asc;-- 默认升序
     * 6.分组：将相同的分成一个组，
     *      select is_show,enable from product group by is_show,enable;
     *      group by后面的列应该大于select后面的列，而且select后面的列必须在group by后面有才行
     * 7.javabean里面的属性的数据类型不能写基本数据类型？
     * ---------------------------------------------------
     * 今日内容：
     * 1.运算符
     * 2.方法，函数
     * 3.排序，分组，分页
     * 4.多表查询：内连接，合并查询，子查询
     * ---------------------------------
     * 后面内容：
     * 1.接口：前后端分离提供给前端接口（servlet）
     * 2.逻辑：返回数据格式化（service）
     * 3.数据：数据持久层（dao）--JDBC|MYBATIS
     *
     */
    /**
     * 2023-2-9 Java后台连接数据库
     * 登录的思路？
     * web前端
     *      1）创建一个登录页面
     *      2）通过点击登录按钮获取用户信息将信息传递到Java后台
     * Java后端
     *      1）servlet  得到前端的数据：六大步骤
     *      2）service  逻辑关系处理，验证码是否正确，用户名和密码是否正确
     *      3）dao      数据持久层 将用户信息和数据库里面的数据进行对比
     *---------------------------------------------------------------
     * 假如前端已经做好，只做后端：必须提供给前端访问的接口：webServlet
     * Java后台得到前端的值，以后封装到vo里面去
     * java和前端之间相互通信时通过什么样的格式？
     * 一般情况下都是以json的格式进行交互
     * {
     *     “key":"value",
     *     "key":"value"
     * }
     * 前端可能得到Java后台的值的数据类型有
     * 1.整形
     * 2.字符串
     * 3.对象
     * 4.数组或者集合
     * 前端要求Java后台能不能返回一个统一的格式？
     * Java和数据库的对象一一对应   model
     * 前端传递到Java后台的数据用的是  VO
     * java传递到前端也应该有一个自己的对象  dto 数据传输对象
     * ----------------------------------------------
     * servlet 六大步骤
     * service  逻辑处理
     *      1）验证码判断  只有验证码正确才查询用户名和密码
     *      2）查询用户名和密码
     *          将vo里面的数据复制到model
     *          同时，将密码加密后存入到model
     *          密码加密的方式有很多种，直接用jdk自带的加密方式，md5；
     *      3）将查询的结果赋值到ResultDTO
     * dao 层   连接数据库
     *      1)通过sql语句去数据库查询
     *      2）调用连接数据库的方法
     * JDBC 六大步骤
     * 面试？PreparedStatement和Statement的区别？
     * ------------------------------------------
     * 1:流程图：
     * 2：类图：rose  powerdesinger
     * 3：er图
     * 4：时序图
     * 5：用例图
     * ------------
     * 燃尽图
     */
    /**
     * 2023-2-10 Java后台的CRUD（增删改查）
     * 登录逻辑思路：
     * 1.登录有验证码，用户名，密码（postman测试）
     * 2.servlet   LoginServlet.java
     *      1)乱码处理
     *      2）得到前端的值
     *      3）封装到VO，VO就是用于封装前端传递到后台的值
     *      4）调用服务逻辑层
     *      5）得到服务逻辑层传回的数据（DTO） 后端传递到前端的数据
     *      6）将得到的数据转换为json对象传递到前端
     * 3.service  服务逻辑层
     *      UserService.java
     *      UserServiceImpl.java  多态
     *      1）判断验证码是否正确
     *      2）对密码进行加密
     *      3）将VO里面的数据复制到model里面
     *      4）逻辑判断，传递到前端应该传什么数据
     * 4.dao   数据持久层
     *      UserDao.java
     *      UserDaoImpl.java
     *      1）封装sql语句
     *      2）调用JDBC的查询方法
     *      3）解析结果集ResultSet
     * 5.JDBC   连接数据
     *      1）加载驱动
     *      2）得到数据库连接
     *      3）编译sql语句
     *      4）执行sql语句
     *      5）返回得到的结果集
     *      6）关闭连接
     * ------------------------------------------
     * 用户新增：思路
     * 前端逻辑：
     * 1.打开页面
     * 2.输入用户信息
     * 3.判断用户信息是否输入格式正确
     * 4.提交信息到Java后台
     * 后端逻辑：
     * 1.servlet  六大步骤
     * 2.service
     *      1）将VO里面的数据复制到model
     *      2）将密码加密
     *      3）根据返回的结果判断是否返回什么ResultDto
     * 3.dao
     *      1）sql语句
     *      2）调用JDBC
     *      3）返回结果
     * 4.JDBC
     *----------------------------------------
     * 删除用户：
     * servlet  六大步骤
     * service  逻辑处理
     * dao  sql编写
     * ------------------------------------
     * 今日任务：
     * Java后台：所有的增删改查操作都做完
     * 下节课：
     * 封装 dto和文件上传
     *
     *
     */
    /**
     * 2023-2-13 后台代码封装和文件上传
     * 1.菜系：思路？学会画图：流程图，类图
     *      1）对象：CuisineModel
     *      2）表：cuisine 多了几个固定的列
     *      3）web或者Java代码的编写（不分先后：可以同时开发）
     *      4）web端：
     *          1：创建html页面
     *          2：用户输入信息：判断输入的格式是否正确
     *          3：将信息提交给后台
     *      5）Java端
     *          1：servlet  六大步骤
     *          2：service  服务逻辑处理
     *          3：dao   sql语句和解析结果集
     *      6）JDBC的使用
     *----------------------------------------------------
     * 以后查询所有的时候，不能直接写select * from 表
     * 必须跟一个分页:默认显示多少条数据
     * mysql 书写关键字的顺序，分页放在最后
     * 查询所有的时候，最好将根据当前条件查询的总条数得到
     * 很多时候，我们需要得到最后一页，则用总条数除以每一页显示的条数即可
     * 查询总条数一共和查询所有的条件一模一样，只不过查询所有多了一个分页
     * -----------------------------------------------------
     * 正常情况下，每一个表都应该有六个操作
     *   增加
     *   修改
     *   删除
     *   根据id查询
     *   根据模糊查询
     *   查询总条数
     * ------------------------------------------------
     * 注意：BaseVO不建议大家在这里用：因为用Lombok包的时候拿不到父类
     * public interface BaseService<T>  这里泛型
     * 产品思路？Java端
     * 1：servlet
     * 2：service 将DTO封装 将dao层提到全局变量
     * 3:dao
     * ----------------------------------
     * 上传图片的时候，应该拿到一个图片在服务器上的地址，怎么拿？
     * 思路：？
     * 1.需要访问服务器的地址
     * 2.在服务器得到前端的数据
     * 3.将前端的数据封装到某个地方？（临时目录，缓存）
     * 4.将文件保存到具体地址
     * 5.将保存的地址返回给前端
     * 注意：默认图片保存到out里面，这里需要将图片复制到web目录下
     */
    /**
     * 2023-2-14 登录，用户管理
     * x-admin的模板内容不要去修改，直接复制出来引用即可
     * 1.复制X-admin的项目到web目录下
     * 2.复制login.html文件到自己的html文件包里面
     * 3.将所有的引入外部地址修改为绝对路径
     * 4.将js通过外部文件引入,不要把js写在html里面
     * --------------------------------
     * 用户查询
     * 1.复制页面，删除表格
     * 2.复制layui里面的<table class="layui-hide" id="test" lay-filter="test"></table>
     * 3.复制js   table.render({
     * 4.添加加载模板： let table = layui.table;
     * 5.修改table.render({
     * 6.再web端将得到的数据打印出来
     * 7.用模板将需要修改的列展示出来
     * ------------------------------------
     * 今日知识点：
     * 1.js的数据类型
     * 2.js的定义
     * 3.js的方法
     * 4.js的数据传输  session
     * 5.得到焦点
     * 6.js的取值赋值
     * 7.ajax调用后台
     * 8.layui.msg 弹出提示信息
     * 9.跳转页面
     * 10.时间格式化
     * 11.定时器
     * 12.表单渲染
     */
    /**
     * 2023-2-15 用户新增修改删除
     * 1.如果前端时间需要年月日，不需要时分秒，则一般情况下再数据库里面操作即可
     * 2.正常情况下，以后所有的查询都不能用* 查询所有列
     * 3.删除思路逻辑？
     *      1：点击删除按钮需要对其进行监听
     *      2：对于重要的信息删除应该给用户提示
     *      3:通过ajax调用后台
     *      4：根据后台代码返回的数据进行逻辑操作
     * 4.新增：？
     *      1：有新增页面
     *      2:监听提交按钮
     *      3：得到值
     *      4：传递到Java
     *      5：根据Java返回的值进行逻辑判断
     * 5.日期框弹出：强制： trigger: "click"
     * 6.对于有些输入框需要做字符格式验证：正则表达式
     *      前提：
     *      1）required="" 要求检测
     *      2）lay-verify="email" 对于自定义验证的正则表达式
     *      3)layui有一个默认的验证，自定义验证会覆盖自身的验证
     * 7.对于复选框，得不到值$("input[type=checkbox][name=hobby]:checked").each(function (index, obj) {
     * 8.js数组转换为字符串
     * 9.点击编辑按钮，弹出编辑页面：一般情况下不要和密码一起修改
     * 10:修改的思路？
     *      1：点击修改按钮弹出修改页面
     *      2：根据id将当前数据查询出来，显示在页面上
     *      3：点击提交按钮进行修改
     *      4：ajax需要添加一个id
     *-------------------------------------------------
     * 今日知识点：
     * 删除：工具栏监听，提示是否删除，调用ajax
     * 新增：表单得到里面的值，复选框难一点：数组和字符串相互转换
     * 编辑：对表单进行赋值：form.render();
     * 双重for循环
     * js里面div对象的遍历
     * js取值赋值
     *
     */
    /**
     * 2023-2-16 产品
     * 产品查询：
     *      1：html页面
     *      2：js文件
     *      3：Java后台
     *      做查询时，如果有条件查询，则对于时间和数字都应该有区间查询
     *      比如：年龄
     *      1）查询年龄小于5的
     *      2）查询年龄大于10的
     *      3）查询年龄在5到10之间的
     * 在index.html里面修改产品
     * ------------------------------
     * 产品新增：
     *  1：页面
     *      页面需要得到时属于哪个菜系，菜系的数据应该来源于数据库
     *  2：js  首先加载模板，然后加载菜系数据
     *  3：Java 后台
     *  注意：
     *  1）添加的时候修改产品的路径
     *  2)文件上传成功以后，将文件路径定义一个全局变量，在提交按钮时，直接得到
     *  -------------
     *  编辑产品的思路
     *  1）html页面
     *  2）js文件
     *      1：加载form表单
     *      2：加载菜系
     *      3：将需要修改的数据赋值到页面
     *      4：点击提交按钮进行提交
     *  3)java后台
     *  ---------------------------------
     *  今日知识点：
     *  1）对于有多个表，则需要在页面加载时先加载另一个表的数据（菜系）
     *  2）文件上传：需要将图片的地址得到，设置了一个全局变量
     *  3）点击修改提交按钮时，得到图片地址和id
     *  4）只要涉及到页面赋值，则需要重新渲染数据：form.render();//重新渲染表单
     *  5）页面赋值三种形式
     *          1：input 表单赋值 $("#id").val(data.cuisineId);
     *          2:div 赋值 $("#id").html(data.cuisineId);
     *          3：修改div属性赋值 $("#demo1").attr("src", data.imgHref);
     *  6）加载先后顺序的问题：先加载菜系，然后根据id查询，然后赋值到页面，然后渲染
     */
    /**
     * 2023-2-17 session安全认证和富文本
     * 总结：
     * 产品增加：
     *      1：创建页面 如果要对输入框进行验证，则需要required="" lay-verify="username"
     *      2：创建js
     *          1）页面加载完成执行里面的代码 $(function(){})
     *          2)加载layui的模板：layui.use([],function(){})
     *          3)监听提交按钮
     *              form.on('submit(add)',function(data){//data拿到form表单
     *              data=data.field;// field 对应的是name属性
     *              如果有文件上传，则另外拿
     *              data.imgHref=imgHref;
     *              如果是复选框，则也需要单独拿数据
     *              可以对复选框进行遍历(如用户新增爱好)
     *              这里的data即拿到所有我们需要的数据
     *              通过ajax传递到Java后台
     *              $.ajax({
     *              url:'/back/product/add',
     *              data:data,
     *              type:'post',
     *              dataType:'json',
     *              success:function(res){
     *              //根据res返回的数据进行逻辑处理
     *              }
     *              });
     *                  return false;//不让刷新页面
     *              })
     *           4)文件上传：需要得到文件上传后返回的值的地址
     *              imgHref = res.data;
     *------------------------------------------------------
     * 对前端js里面到处都在使用ajax，所以可以考虑将ajax的代码提取到公共的js
     * myAjax.js一定要移到jQuery.js的后面，其他js之前
     * ------------------------------------------
     * 对于后台管理系统来说，不能所有人都可以访问，必须登录
     * 前端：不能让用户直接访问页面?
     * 当用户访问页面的时候，判断用户是否已经登录即可？
     * 判断登录用js来操作，因为每一个页面都有myAjax.js文件，则直接写到里面即可
     * 怎么判断是否已经登录？登录或者没有登录应该有一个标识，
     * 所以在登录成功以后可以设定一个标识符，在其他页面访问的时候，查看当前标识符是否存在即可
     * 在其他页面如果拿不到标识符，则直接返回登录页面即可
     * 一定不要在页面加载完成执行判断用户是否已经登录
     * -------------------------------
     * 对于有个别用户可以直接访问后台接口，也能做相应的操作，这也是不符合标准
     * 所以在后台应该有一个登录标识，判断是否已经登录，而且应该拦截所有访问后台的接口地址
     * 这里需要用到过滤器
     * ---------------------------
     * 对于session安全认证：前后端都必须判断是否已经登录
     * -----------------------------------
     * 模糊查询：
     * 模糊查询条件：根据查询所有的展示数据来判断应该有哪些模糊查询条件
     *
     */
    /**
     * 2023-2-20 富文本编辑器
     * 1.引入wangeditor的js代码
     * 2.复制html代码
     * 3.在js里面添加加载富文本的js
     *      1:修改连接后台的文件地址：const editUrl = '/upload';//服务器访问地址
     *      2：要将传递到前端的地址进行回显到html：insertImg(url)//回显到富文本里面
     * 4.对富文本进行取值赋值
     *      1：取值：editor.txt.html();
     *      2：赋值：editor.txt.html(data.content);
     *--------------------------------------------------------
     * 第四阶段js要用到的知识点;
     * 1.数据类型
     *      五大数据类型：数字，字符，对象，数组，布尔
     *      数字对应Java的整数和小数
     *          1）随机数2）取大取小
     *      字符对应Java的String
     *          1）字符串拼接 2）字符转换为数组 3）替换 4）startWith，endWith，contains
     *          5）indexOf   length  6)不区分单双引号
     *      对象对应Java的类
     *          JSON对象{"key":"value"}，普通对象{key:"value"}
     *      数组对应Java的List<Object>
     *          let arr=[1,"a",true,[],{}];
     *      布尔对应Java的布尔   true,false
     * 2.语法结构 if else for
     * 3.取得对象
     *      $("#id")     得到一个对象
     *      $(".className")     得到一组对象
     *      $("input[type=radios][name=hobby]") 得到一组对象
     *      对于不唯一的，一组对象，则需要进行遍历
     *      array.each(function(index,obj){
     *          index //索引 o开始
     *          obj  对象
     *      })
     * 4.方法：和Java一样  小驼峰命名 ，可以有返回值 ，还有参数，不用写数据类型
     *      function methodName(pramName){
     *          return value;
     *      }
     * 5.注意加载顺序：
     *      1）jquery.js
     *      2) myAjax.js  //里面有判断是否已经登录
     *      3) layui.use([],function({}))
     *      4) wangEditor.js
     * 6.监听table，监听按钮
     * 7.table.render({
     * 8.文件上传
     * 9.富文本
     * 10.定时器
     * ---------------------------
     *前后端传值：以后无论哪种语言都固定为json对象
     *
     */
    /**
     * 2023-2-21 第五阶段redis基础
     * 1.定义是什么？
     * 2.为什么要学？优势
     * 3.可以应用在哪些地方？应用场景
     * 4.怎么做？
     * -------------------------------
     * 思考？如果产品做一个秒杀事件，
     * 假如有十万人同时抢产品，则会由十万人同时访问产品详细页面
     * 以前页面上所有数据都来自于数据库，则数据库访问连接太多直接崩溃
     * 只要第一个人访问数据库后，则不让后面的人访问数据库
     * 第一个人访问后给一个标识符，并存入到某个地方，并且将刚刚访问的数据存起来
     * 第二个人取访问的时候直接看是否由这个标识符
     * 如果有，则直接拿到刚刚的数据
     * 如果没有，则直接访问数据库
     * CompanyModel companyModel=new CompanyModel();
     * boolean isHave=redis.exist("companyModel");
     * if(isHave){
     *      companyModel=redis.get("companyModel");
     * }else{
     *     companyModel=companyDao.getCompanyModel();
     *     redis.set("companyModel",companyModel);
     * }
     * -----------------------------------
     * 所以，如果管理员修改了数据库里面的信息，则应该删除redis关于companyModel里面的数据
     * int count=companyDao.update(companyModel);
     * if(count>0){
     *     redis.delete("companyModel");
     * }
     * --------------------------------
     * 删除key值可以手动删除也可以设置过期时间
     * 如果再次对同一个key进行赋值，则后面的会覆盖前面的值
     * 一般情况下，key，value后面的值会覆盖前面的值；
     * ------------------------------------
     * list集合：
     * 如果这个key存在，则一致会在list的末尾进行添加数据
     * list如果要删除，则应该删除所有的key
     * ------------------------------
     * 第七阶段redis集成
     * 1.导包
     * 2.复制工具类 String  List<String,String>,List<Object,Object>
     *
     */
}
